package com.ssk.dev.fs.ace

import org.apache.poi.xssf.usermodel.XSSFSheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.*
import java.util.*
import kotlin.collections.HashMap


class AceMain {


    companion object {

        private const val SHEET_UMENG = "Umeng"
        private const val SHEET_UMENG_New = "UmengNew"
        private const val DELIMITERS = ") at"
        private const val TYPE_NPE = "java.lang.NullPointerException"
        private const val TYPE_NFE = "java.lang.NumberFormatException:"



        @JvmStatic
        fun main(args: Array<String>) {
            val dst = "/Users/tangsong/Desktop/crash-analysis.xlsx"
            val file = FileInputStream(File(dst))

            val workbook = XSSFWorkbook(file)

            val toMergeSheet = workbook.getSheet(SHEET_UMENG_New)

            if (toMergeSheet == null) {
                println(" cannot find sheet : $SHEET_UMENG_New")
                return
            }

            if (toMergeSheet.count() <= 0) {
                println("find sheet ：$SHEET_UMENG_New, but it's empty !!!")
                return
            }

            val newData = analyse(toMergeSheet)

            println(toMergeSheet.sheetName)
            println(toMergeSheet.count())
            assert(toMergeSheet.count() == newData.count())

            val workingSheet = workbook.getSheet(SHEET_UMENG)
            merge(workingSheet, newData)


            try {
                val out = FileOutputStream(File("/Users/tangsong/Desktop/crash-analysis-update.xlsx"))
                workbook.write(out)
                out.close()
                println("Excel written successfully..")
            } catch (e: FileNotFoundException) {
                e.printStackTrace()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }

        private fun analyse(sheet: XSSFSheet): LinkedList<UMengData> {

            val list = LinkedList<UMengData>()

            sheet.forEach { row ->
                if (row.getCell(0) == null) {
                    println(" cell is null")
                } else {
                    val exceptionAnalysis = row.getCell(0).stringCellValue.split(DELIMITERS)
                    val type = if (exceptionAnalysis[0].startsWith(TYPE_NPE)) {
                        "NPE"
                    } else {
                        ""
                    }
                    list.add(
                        UMengData(
                            exceptionAnalysis[0],
                            row.getCell(0).stringCellValue,
                            row.getCell(1).stringCellValue,
                            row.getCell(3).numericCellValue.toString(),
                            row.getCell(4).numericCellValue.toString(),
                            row.getCell(5).stringCellValue,
                            type
                        )
                    )
                }

            }

            return list
        }

        private fun merge(sheet: XSSFSheet, newList: LinkedList<UMengData>) {

            val newMap = HashMap<String, UMengData>(newList.size)
            newList.forEach {
                newMap[it.key] = it
            }

            val sheetIt = sheet.iterator()

            while (sheetIt.hasNext()) {
                val row = sheetIt.next()

                val keys = row.getCell(0)?.toString()?.split(DELIMITERS)
                if (keys.isNullOrEmpty()) {
                    println("ignore row : ${row.getCell(0)}")
                   continue
                }

                val newItem = newMap[keys[0]]
                if (newItem != null) {
                    //更新现有row
                    //错误次数
                    row.getCell(4).setCellValue(newItem.errorCount.toDouble())
                    row.getCell(5).setCellValue(newItem.errorCount.toDouble())
                    row.getCell(6).setCellValue(newItem.status)
                    newMap.remove(keys[0])
                    println(" update rows : " + row.getCell(0).stringCellValue)
                }

            }

            println(" add new items : ${newMap.values.size}")
            newMap.values.forEach { data ->
                //在末尾新增
                sheet.createRow(sheet.count()).apply {
                    createCell(0).setCellValue(data.summery)
                    createCell(1).setCellValue(data.version)
                    createCell(2).setCellValue(data.type)
                    createCell(3).setCellValue("TODO")
                    createCell(4).setCellValue(data.errorCount.toDouble())
                    createCell(5).setCellValue(data.errorUserCount.toDouble())
                    createCell(6).setCellValue(data.status)
                }
            }





        }
        private fun merge(currentList: LinkedList<UMengData>, newList: LinkedList<UMengData>) {

            val currentMap = HashMap<String, UMengData>(currentList.size)

            currentList.forEach {
                currentMap[it.key] = it
            }

            newList.forEach { newItem ->
                val old = currentMap[newItem.key]
                if (old != null) {

                }
            }


        }
    }
}